package com.avecsys.quotemanager.service.buyer;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.avecsys.quotemanager.constants.BusinessCodes;
import com.avecsys.quotemanager.dao.buyer.BuyerMasterDAO;
import com.avecsys.quotemanager.dao.common.EnumDBRecordStatus;
import com.avecsys.quotemanager.dao.common.EnumTransactionStatus;
import com.avecsys.quotemanager.dao.user.UserMasterDAO;
import com.avecsys.quotemanager.exception.BusinessException;
import com.avecsys.quotemanager.exception.DAOException;
import com.avecsys.quotemanager.pojos.BuyerMasterPojo;
import com.avecsys.quotemanager.pojos.BuyerUsersPojo;
import com.avecsys.quotemanager.pojos.SupplierMasterPojo;
import com.avecsys.quotemanager.pojos.UserMasterPojo;
import com.avecsys.quotemanager.service.security.CryptoService;
import com.avecsys.quotemanager.utils.TransactionStatus;
import com.avecsys.quotemanager.vo.BuyerVO;

public class BuyerMasterServiceImpl implements BuyerMasterService
{

	private static final Log log = LogFactory.getLog(BuyerMasterServiceImpl.class);

	private BuyerMasterDAO buyerMasterDAO;

	private UserMasterDAO userMasterDAO;

	private CryptoService cryptoService;

	@Override
	public TransactionStatus deleteBuyerMaster(BuyerMasterPojo buyerMasterPojo) throws BusinessException
	{
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.DELETE_FAIL.ordinal());
		try
		{
			transactionStatus = this.buyerMasterDAO.deleteBuyer(buyerMasterPojo);
		}
		catch (DAOException e)
		{
			throw new BusinessException(e);
		}
		return transactionStatus;
	}

	/**
	 * Method to return all the Buyers who belongs to a Supplier
	 * 
	 * @param supplierMasterPojo
	 * @return
	 * @throws BusinessException
	 */
	@Override
	public List<BuyerMasterPojo> getAllBuyers(SupplierMasterPojo supplierMasterPojo)
			throws BusinessException
	{
		try
		{
			return this.buyerMasterDAO.findAllSupplierBuyers(supplierMasterPojo);
		}
		catch (DAOException e)
		{
			throw new BusinessException(e);
		}
	}

	@Override
	public List<BuyerUsersPojo> getAllUsers(BuyerMasterPojo buyerMasterPojo) throws BusinessException
	{
		try
		{
			return this.userMasterDAO.findAllUsersByBuyer(buyerMasterPojo);
		}
		catch (DAOException e)
		{
			throw new BusinessException(e);
		}
	}

	@Override
	public BuyerMasterPojo getBuyerMasterById(Long buyerId) throws BusinessException
	{
		BuyerMasterPojo buyerMasterPojo = new BuyerMasterPojo();
		try
		{
			buyerMasterPojo = (BuyerMasterPojo) this.buyerMasterDAO.findActiveById(buyerMasterPojo, buyerId);
		}
		catch (DAOException e)
		{
			throw new BusinessException(e);
		}
		return buyerMasterPojo;
	}

	public BuyerMasterDAO getBuyerMasterDAO()
	{
		return this.buyerMasterDAO;
	}

	/**
	 * @return the cryptoService
	 */
	public CryptoService getCryptoService()
	{
		return this.cryptoService;
	}

	public UserMasterDAO getUserMasterDAO()
	{
		return this.userMasterDAO;
	}

	@Override
	public boolean isBuyerEmailNotRegistered(BuyerVO buyerVO) throws BusinessException
	{
		boolean isEmailNotRegistered = true;
		try
		{
			BuyerMasterPojo buyerMasterPojo = getBuyerMasterById(buyerVO.getBuyerId());
			List<UserMasterPojo> userMasterPojoList = this.userMasterDAO.findAllActiveBuyerUsersByEmail(buyerVO.getDefaultAdminUserEmail());

			// If Existing Buyer
			if ((buyerMasterPojo != null) && buyerMasterPojo.isPersisted())
			{
				for (UserMasterPojo userMasterPojo : userMasterPojoList)
				{
					if (userMasterPojo.getBuyerUsersPojo().size() > 0)
					{
						// Get The buyer associated
						for (BuyerUsersPojo buyerUsersPojo : userMasterPojo.getBuyerUsersPojo())
						{
							// If a different buyer has the same email id
							if (!buyerUsersPojo.getBuyerMasterPojo()
									.getBuyerId()
									.equals(buyerVO.getBuyerId()))
							{
								isEmailNotRegistered = false;
								break;
							}
							else
							{
								// If Same Buyer and different user has the
								// same email id and in add new supplier user
								// case
								if (buyerVO.getBuyerUserId() == null)
								{
									isEmailNotRegistered = false;
									break;
								}
								else
								{
									// If Edit Buyer User case and the same
									// email is allocated for different user
									// already then
									if (!buyerUsersPojo.getBuyerUserId()
											.equals(buyerVO.getBuyerUserId()))
									{
										isEmailNotRegistered = false;
										break;
									}
								}
							}
						}
					}
				}
			}
			else
			{
				// If New buyer
				for (UserMasterPojo userMasterPojo : userMasterPojoList)
				{
					if (userMasterPojo.getBuyerUsersPojo().size() > 0)
					{
						isEmailNotRegistered = false;
					}
				}
			}
		}
		catch (DAOException e)
		{
			throw new BusinessException(e);
		}
		return isEmailNotRegistered;
	}

	@Override
	public TransactionStatus saveBuyerMaster(BuyerVO buyerVo) throws BusinessException
	{
		// Initial Transaction state when save operation
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.SAVE_FAIL.ordinal());
		try
		{
			/*
			 * if (!isSupplierEmailNotRegistered(supplierMasterPojo)) {
			 * transactionStatus
			 * .setStatus(EnumTransactionStatus.BUSINESS_FLOW_FAIL .ordinal());
			 * transactionStatus.setErrorFieldName("emailId"); }
			 */
			// Step1:
			// if the Buyer Master information already persisted then update
			// other wise create a new buyer information with default use
			// Mark As Active
			buyerVo.getBuyerMasterPojo().setStatus(EnumDBRecordStatus.ACTIVE.status());
			if (buyerVo.getBuyerMasterPojo().isPersisted())
			{
				// Initial Transaction State when update operation
				transactionStatus.setStatus(EnumTransactionStatus.UPDATE_FAIL.ordinal());
				transactionStatus = this.buyerMasterDAO.updateBuyer(buyerVo.getBuyerMasterPojo());
			}
			else
			{
				// Create New Buyer With Default Administrator
				BuyerUsersPojo buyersUsersPojo = createDefaultAdminInstance(buyerVo);
				buyerVo.getBuyerMasterPojo().getBuyerUsers().add(buyersUsersPojo);
				transactionStatus = this.buyerMasterDAO.saveBuyer(buyerVo.getBuyerMasterPojo());
			}
		}
		catch (DAOException e)
		{
			log.error(e);
			throw new BusinessException(e);
		}
		return transactionStatus;
	}

	public void setBuyerMasterDAO(BuyerMasterDAO buyerMasterDAO)
	{
		this.buyerMasterDAO = buyerMasterDAO;
	}

	/**
	 * @param cryptoService the cryptoService to set
	 */
	public void setCryptoService(CryptoService cryptoService)
	{
		this.cryptoService = cryptoService;
	}

	public void setUserMasterDAO(UserMasterDAO userMasterDAO)
	{
		this.userMasterDAO = userMasterDAO;
	}

	/**
	 * Method to create the default Admin user for the supplier
	 * 
	 * @param supplierVO
	 * @return SupplierUsersPojo instance
	 */
	private BuyerUsersPojo createDefaultAdminInstance(BuyerVO buyerVo)
	{
		// Create User Instance
		UserMasterPojo userMasterPojo = new UserMasterPojo();
		userMasterPojo.setUserName("Admin");
		userMasterPojo.setPassword(this.cryptoService.encryptPassword("password"));
		userMasterPojo.setEmail(buyerVo.getDefaultAdminUserEmail());
		userMasterPojo.setEmailVerfied(Boolean.FALSE.toString());
		userMasterPojo.setUserType(BusinessCodes.USER_TYPE_BUYER);
		userMasterPojo.setStatus(EnumDBRecordStatus.ACTIVE.status());
		// Audit User Information
		userMasterPojo.setCreatedDttm(buyerVo.getBuyerMasterPojo().getModifiedDttm());
		userMasterPojo.setCreatedUserId(buyerVo.getBuyerMasterPojo().getModifiedUserId());
		userMasterPojo.setModifiedDttm(buyerVo.getBuyerMasterPojo().getModifiedDttm());
		userMasterPojo.setModifiedUserId(buyerVo.getBuyerMasterPojo().getModifiedUserId());

		// Create Buyer User Instance
		BuyerUsersPojo buyerUsersPojo = new BuyerUsersPojo();
		buyerUsersPojo.setIsAdmin(Boolean.TRUE.toString());
		buyerUsersPojo.setUserMasterPojo(userMasterPojo);
		buyerUsersPojo.setBuyerMasterPojo(buyerVo.getBuyerMasterPojo());
		buyerUsersPojo.setStatus(EnumDBRecordStatus.ACTIVE.status());

		// Audit User Information
		buyerUsersPojo.setCreatedDttm(buyerVo.getBuyerMasterPojo().getModifiedDttm());
		buyerUsersPojo.setCreatedUserId(buyerVo.getBuyerMasterPojo().getModifiedUserId());
		buyerUsersPojo.setModifiedDttm(buyerVo.getBuyerMasterPojo().getModifiedDttm());
		buyerUsersPojo.setModifiedUserId(buyerVo.getBuyerMasterPojo().getModifiedUserId());
		return buyerUsersPojo;
	}

}
